package cn.boodqian.util;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;

import android.text.TextUtils;

import junit.framework.Assert;

public class GAERequest {
	//private final static String[] m_IPs = new String[] {"203.208.46.1","203.208.46.2","203.208.46.3","203.208.46.4","203.208.46.5","203.208.46.6","203.208.46.7","203.208.46.8"};
	public static String[] mIPs = new String[] {"203.208.47.81","203.208.46.240","203.208.45.208","203.208.47.82","203.208.46.241","203.208.45.209","203.208.47.83","203.208.46.242","203.208.45.210"};
	//public static String[] mIPs = new String[] {"203.208.49.1","203.208.49.2"};
	//private final static String[] m_IPs = new String[] {"10.0.2.2:8888"};
	public static Integer mLastIPIndex = 0;
	private String appname;
	private String hostname;
	private String lasterror = "";
	private final static String m_UrlFormat = "http://%s%s";
	private final static String m_HostFormat = "%s.appspot.com";
	public GAERequest(String appname) {
		assert(appname!=null && appname.length()>0);
		this.appname = appname;
		this.hostname = String.format(m_HostFormat, appname);
	}
	
	// synchronize should be done by caller
	private boolean updateIPs() {
		return false;
	}
	
	// path: "/airdata"
	public String doGet(String path) {
		Assert.assertTrue(path, path.startsWith("/"));
		Log.i("Requesting="+path);
		StringBuilder builder = new StringBuilder();
		boolean updated = false;
		String[] localIPs = null;
		
		synchronized(mIPs) {
			localIPs = new ArrayList<String>(Arrays.asList(mIPs)).toArray(new String[]{});
		}
		for(int i=0;i<localIPs.length;i++) {
			URL url;
			try {
				String ip = localIPs[i];

				// Try last success IP first
				synchronized(mLastIPIndex) {
					if( i == 0 && mLastIPIndex < localIPs.length ) {
						ip = localIPs[mLastIPIndex];
					} else if( i == mLastIPIndex ) {
						ip = localIPs[0];
					}
				}

				Log.i("Trying "+ip);
				url = new URL(String.format(m_UrlFormat, ip, path));
				HttpURLConnection connection = (HttpURLConnection) url.openConnection();
				connection.setRequestProperty("Host", hostname);
				connection.setConnectTimeout(7000);
				BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

				String line;
				while ((line = reader.readLine()) != null) {
					builder.append(line);
				}

				// Find out the success IP index
				synchronized(mLastIPIndex) {
					for( int j=0;j<mIPs.length;j++ ) {
						if( ip.compareTo(mIPs[j]) == 0 ) {
							mLastIPIndex = j;
							break;
						}
					}
				}

				break;
			} catch (Exception e) {
				builder.setLength(0);
				e.printStackTrace();
				lasterror = e.toString();

				if( !updated && i==localIPs.length-1) {
					updated = true;
					synchronized(mIPs) {
						if( updateIPs() ) {
							Log.i("Google IP updated, retry...");
							localIPs = new ArrayList<String>(Arrays.asList(mIPs)).toArray(new String[]{});
							i = -1; // start over again
						}
					}
				}
			}
		}

		//Log.i("Response="+builder.toString());
		String ret = null;
		if(builder.length()>0)  ret=builder.toString();
		return ret;
	}
	
	public String getLastError() {
		return lasterror;
	}
}
